//得到一个计时器对象，该对象提供了两个方法
function getTimer(duration,thisArg,callback){
    var timer
    return {
        start:function(){
            if(timer){
                return
            }
            timer = setInterval(callback.bind(thisArg),duration)
        },
        stop:function(){
            clearInterval(timer)
            timer = null
        },
    }
}
//获取一个随机数
function getRandom(min,max){
    return Math.floor(Math.random()*(max-min+1)+min)
}
//游戏对象
var game = {
    isOver:false,
    isPause:true,//游戏是否暂停
    dom:document.querySelector(".game"),//游戏dom元素
    overDom:document.querySelector(".game .over"),//游戏结束dom元素
    width:document.querySelector(".game").clientWidth,//得到游戏面板宽度
    height:document.querySelector(".game").clientHeight,//得到游戏面板高度
    start:function(){
        sky.timer.start()
        land.timer.start()
        bird.swingTimer.start()//小鸟扇动翅膀
        bird.dropTimer.start()
        pipeManager.produceTimer.start()
        pipeManager.moveTimer.start()
        hitManager.timer.start()
        this.isPause = false
    },
    stop:function(){
        sky.timer.stop()
        land.timer.stop()
        bird.swingTimer.stop()
        bird.dropTimer.stop()
        pipeManager.produceTimer.stop()
        pipeManager.moveTimer.stop()
        hitManager.timer.stop()
        this.isPause = true
    },

}

//天空对象
var sky = {
    left:0,//当前横坐标
    dom:document.querySelector(".game .sky"),
    
}

sky.timer = getTimer(16,sky,function(){
    this.left -= 1
    this.dom.style.left = this.left + "px"
    console.log("this.left:"+this.left+"this.dom.clientWidth:"+this.dom.clientWidth)
    if(this.left <= -game.width){
        this.left = 0
    }
})
 

//大地对象
var land = {
    left:0,//当前横坐标
    height:document.querySelector(".game .land").clientHeight,
    dom:document.querySelector(".game .land"),
    top:game.height-document.querySelector(".game .land").clientHeight
}

land.timer = getTimer(16,land,function(){
    this.left -= 2
    this.dom.style.left = this.left + "px"
    if(this.left <= -game.width){
        this.left = 0
    }
})

//小鸟对象
var bird = {
    left:150,
    top:150,
    width:33,
    height:26,
    swingIndex:0,//翅膀状态 0-2
    dom:document.querySelector(".game .bird"),
    a:0.002,//加速度
    v:0,//速度
    t:16,//时间间隔
    show(){
        if(this.swingIndex===0){
            this.dom.style.backgroundPosition = "-8px -10px"
        }else if(this.swingIndex===1){
            this.dom.style.backgroundPosition = "-60px -10px"
        }else if(this.swingIndex===2){
            this.dom.style.backgroundPosition = "-113px -10px"
        }
        //设置小鸟的位置
        this.dom.style.left = this.left + "px"
        this.dom.style.top = this.top + "px"
    },
    setTop(top){
        if(top<0){
            top = 0
        }else if(top>(land.top-this.height)){
            top = land.top-this.height
        }
        this.top = top
        this.show()
    },
    jump(){
        this.v = -0.5
    }

}
bird.show()

//翅膀计时器

bird.swingTimer = getTimer(200,bird,function(){
    this.swingIndex = (this.swingIndex+1)%3
    this.show()
})

//掉落的计时器
bird.dropTimer = getTimer(bird.t,bird,function(){
    //计算移动距离
    var dis = this.v*this.t + 0.5*this.a*this.t*this.t
    //改变速度
    this.v += this.a*this.t
    //改变top
    this.setTop(this.top+dis)
})



//柱子
function Pipe(direction,height){
    this.width = Pipe.width
    this.left = game.width
    this.height = height
    this.dom = document.createElement("div")
    this.direction = direction
    //纵坐标
    if(direction === 'up'){
        this.top = 0
    }else{
        this.top = land.top-this.height
    }
    this.dom.className = "pipe "+direction
    this.dom.style.height =this.height+"px"
    this.dom.style.top = this.top+"px"
    this.show();
    game.dom.appendChild(this.dom)
}
Pipe.width = 52;//柱子的宽度
//显示柱子
Pipe.prototype.show = function(){
    this.dom.style.left = this.left + "px"
}
//一对柱子的构造函数
function PairPipe(){
    var minHeight = 60 //最小高度
    var gap = 150 //缝隙
    var maxHeight= land.top - minHeight - gap

    var topHeight = getRandom(minHeight,maxHeight)
    this.up = new Pipe("up",topHeight)
    this.down = new Pipe("down", land.top-topHeight-gap)
    this.left = this.up.left
}

//显示一对柱子
PairPipe.prototype.show = function(){
    this.up.left = this.left
    this.down.left = this.left
    this.up.show()
    this.down.show()
}

//移除一对柱子
PairPipe.prototype.remove = function(){
    this.up.dom.remove()
    this.down.dom.remove()
}
//柱子控制器，用于不断地创建柱子，并且控制柱子移动

var pipeManager = {
    pipes:[],//保存所有的柱子对
    producePair(){
        this.pipes.push(new PairPipe())
    }
}

pipeManager.produceTimer = getTimer(1000,pipeManager,function(){
    this.producePair()
})
pipeManager.moveTimer = getTimer(16,pipeManager,function(){
    for(var i=0;i<this.pipes.length;i++){
        var pairPipe = this.pipes[i]
        pairPipe.left -= 2
        if(pairPipe.left<=-Pipe.width){
            pairPipe.remove()
            this.pipes.splice(i,1)
            i--
        }else{
            pairPipe.show()
        }
    }
})


//碰撞检测器
var hitManager = {
    //检测是否与天空碰撞
    validate:function(){
        if(bird.top<=0){
            return true
        }else if(bird.top>=land.top-bird.height){
            return true
        }

        for(var i=0;i<pipeManager.pipes.length;i++){
            var pairPipe = pipeManager.pipes[i]
            if(this.validateBirdAndPipe(pairPipe.up)||this.validateBirdAndPipe(pairPipe.down)){
                return true
            }
        }

        return false
    },
    validateBirdAndPipe(pipe){//判断某根柱子与小鸟是否发生碰撞
        var bx = bird.left + bird.width/2;
        var by = bird.top + bird.height/2;
        var px = pipe.left + pipe.width/2;
        var py = pipe.top + pipe.height/2;
        if(Math.abs(bx-px)<=bird.width/2+pipe.width/2 && Math.abs(by-py)<=bird.height/2+pipe.height/2){
            return true
        }else{
            return false
        }
    }
}
hitManager.timer = getTimer(16,hitManager,function(){
    //检测是否碰撞
    if(hitManager.validate()){
        game.stop()
        game.isOver = true
        game.overDom.style.display = "block"
    }
})


window.onkeydown = function(e){
    if(e.key == "Enter"){
        if(game.isOver){
            window.location.reload()
            return
        }
        if(game.isPause){
            game.start()
        }else{
            game.stop()
        }
    }
    if(e.key == " "){
        bird.jump()
    }
}
window.onclick = function(){
    if(game.isOver){
        window.location.reload()
        return
    }
    if(game.isPause){
        game.start()
    }else{
        bird.jump()
    }
}